package com.gem.netty.message;

import com.gem.entity.Card;
import com.gem.entity.Game;
import com.gem.enums.CardType;
import com.gem.enums.GameRoundStageType;
import com.gem.enums.GemType;
import com.gem.enums.MessageColorType;
import com.gem.factory.game.GameFactory;
import com.gem.holder.ThreadLocalFactory;
import com.gem.netty.entity.CardInfo;
import com.gem.netty.entity.ClientContent;
import com.gem.netty.entity.CurrentUser;
import com.gem.netty.message.swap.AbstractSwapBase;
import com.gem.netty.message.swap.GetCard;
import com.gem.netty.session.GroupSessionFactory;
import com.gem.utils.R;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Author: Xhy
 * CreateTime: 2022-09-24 14:32
 *
 * 换牌阶段
 *
 */
public class GetCardMessage implements Message{

    @Override
    public void handler(ClientContent content) {
        ChannelHandlerContext ctx = content.getCtx();
        Game game = GameFactory.get(content.getRoomId());
        String roomId = game.getRoomId();
        CurrentUser user = game.getUsers().get(game.getCurrentIndex());
        AbstractSwapBase getCard = new GetCard();
        R r = getCard.doSwap(content);
        if (!r.getState()){
            ctx.writeAndFlush(new TextWebSocketFrame(r.toString()));
            return;
        }
        // 清空回合宝石库
        clearGem(user);
        // 宝石库补宝石
        addGem(content);
        // 获取当前拿取卡牌信息
        user.setCurrentGetCardInfo(content.getContent().getCardInfo());
        CardInfo cardInfo = user.getCurrentGetCardInfo();
        // 将卡牌存入用户卡牌库
        addCard(game,content.getContent().getCardInfo());
        // 是否换的是用户暂存的牌
        if (existTs(user,cardInfo)){
            Iterator<CardInfo> it = user.getTSCards().iterator();
            while (it.hasNext()){
                CardInfo tsCard = it.next();
                if (tsCard.getNo() == cardInfo.getNo()){
                    it.remove();
                    // 玩家黄金宝石减少
                    TreeMap<Integer, Integer> userOwnGems = user.getGems();
                    userOwnGems.put(GemType.GOLD.type,userOwnGems.get(GemType.GOLD.type)-1);
                    // 宝石库黄金宝石增加
                    Map<Integer, Integer> baseGems = game.getGems();
                    baseGems.put(GemType.GOLD.type,baseGems.get(GemType.GOLD.type)+1);
                    break;
                }
            }
        }else {
            // 清理卡牌库
            GameFactory.reduceGameCard(content,game);
            // 补牌
            GameFactory.getShowCard(game,content);
        }

        // 加分
        addScore(user,cardInfo.getScore());
        // 减少用户手上宝石总数量
        reduceUserTotalGemSize(user);
        // 兑换后是否达到15分
        List<Channel> channels = GroupSessionFactory.getGroupSession().getMembersChannel(content.getRoomId());
        String userName = user.getName();
        if (is15score(user)){
            game.getWins().add(user);
            GameFactory.notifyUsers(channels,R.ok().data("color", MessageColorType.SYSTEM_MESSAGE.type).message(userName +"这哥们有15分了!").type(content.getType()),roomId);
        }
        // 修改用户当前回合状态
        setRoundEndState(user);
        // 告知其他用户
        GameFactory.notifyUsers(channels,R.ok().data("color",MessageColorType.GET_CARD.type).message(userName+" 玩家换取卡牌: "+ CardType.getInfo(cardInfo.getType())
        +","+cardInfo.getScore()+" 分,卡牌buff为:"+GemType.get(cardInfo.getCardBuff()))
                .type(content.getType()),roomId);
        GameFactory.roundStage(roomId);
        ThreadLocalFactory.remove();

    }



    private boolean existTs(CurrentUser user, CardInfo cardInfo) {
        for (CardInfo tsCard : user.getTSCards()) {
            if (tsCard.getNo() == cardInfo.getNo()){
                return true;
            }
        }
        return false;
    }

    private void addGem(ClientContent content) {
        Game game = GameFactory.get(content.getRoomId());
        // 用需要的卡牌 - 使用的卡牌buff = 宝石库增加的数量
        CardInfo cardInfo = content.getContent().getCardInfo();
        Map<Integer, Integer> gemCards = cardInfo.getGemCards(); // 用户的Buff
        Map<Integer, Integer> swapCard = Card.getCardGems(cardInfo.getNo()); // 该卡需要宝石数
        Map<Integer,Integer> needAddGem = new HashMap<>();
        Map<Integer, Integer> replaceGems = cardInfo.getReplaceGems();
        swapCard.forEach((k,v)->{
            Integer goldK = replaceGems.get(k);
            goldK = goldK == null ? 0 : goldK;
            Integer gemCount = v - goldK;
            // buff数量
            Integer number = gemCards.get(k);
            if (number!=null){
                gemCount -= number;
            }
            needAddGem.put(k, gemCount);
        });
        Map<Integer, Integer> gems = game.getGems();
        // 玩家使用的宝石 - 替的宝石的  < 0 ? 0 :  玩家使用的宝石 - 替的宝石的
        needAddGem.forEach((k,v)->{
            gems.put(k,gems.get(k)+v );
        });
        // 是否用了黄金替宝石
        if (replaceGems.size() > 0){
            AtomicInteger number = new AtomicInteger(0);
            replaceGems.forEach((k,v)->{
                number.getAndAdd(v);
            });
            Object tsCard = ThreadLocalFactory.get("isTsCard");
            Boolean isTsCard = false;
            if (tsCard instanceof Boolean){
                isTsCard = (Boolean) tsCard;
            }
            if(isTsCard){
                number.getAndDecrement();
            }
            gems.put(GemType.GOLD.type,gems.get(GemType.GOLD.type)+number.get());
        }
    }

    private void reduceUserTotalGemSize(CurrentUser user) {
        AtomicInteger number = new AtomicInteger(0);
        user.getGems().forEach((k,v)->{
            number.getAndAdd(v);
        });
        user.setGetGemNumber(number.get());
    }

    private boolean is15score(CurrentUser user) {
        return user.getOwnScore() >=15;
    }




    /**
     * 加分
     * @param user
     * @param score
     */
    private void addScore(CurrentUser user, Integer score) {
        user.setOwnScore(user.getOwnScore()+score);
    }

    /**
     * 回合给下一个用户
     */
    /*private void setUserRound(Game game){
        int currentUserIndex = (game.getCurrentIndex()+1) % game.getUsers().size();
        game.setCurrentIndex(currentUserIndex);
        game.setUserId(game.getUsers().get(currentUserIndex).getId());
        // 修改状态
        game.getUsers().get(currentUserIndex).setState(GameRoundStageType.WAIT.type);
    }*/


    /**
     * 修改状态
     * @param user
     */
    private void setRoundEndState(CurrentUser user){
        user.setState(GameRoundStageType.WAIT.type);
    }

    /**
     * 添加卡牌到用户卡库
     * @param game
     */
    private void addCard(Game game,CardInfo cardInfo){
        CurrentUser user = game.getUsers().get(game.getCurrentIndex());

        List<Card> cardList = game.getShowCards().get(cardInfo.getType());
        int i =0;
        for (; i < cardList.size() ; i++) {
            if (cardList.get(i).getNo() == cardInfo.getNo()){
                break;
            }
        }

        user.getCards().get(cardInfo.getCardBuff()).add(Card.getCard(cardInfo.getNo()));
    }






    /**
     * 清空回合宝石库
     * @param user
     */
    private void clearGem(CurrentUser user){
        user.getCurrentGemState().clear();
    }
}
